package opt;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;

import ag.AlgoritmoGenetico;
import ag.Individuo;
import ag.TorneoBinario;
import on.Configuration;

public class Principal {

	private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("tesis");
	private static EntityManager em = emf.createEntityManager();
	private static Runtime runtime = Runtime.getRuntime();
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		/*
		 * Para cada configuracion
		 * 	Para cada carga de la red
		 * 		Correr 100000 veces
		 */
		
		Set<Individuo> poblacion = new HashSet<Individuo>();
		long inicio = System.currentTimeMillis();
		
		for(int c = 0; c < 32; c++){
			
			int k = c % 8;
			
			boolean fibraFlexible = (k / 4 >= 1);
			k = k % 4;
			
			boolean bandaFlexible = (k / 2 >= 1);
			k = k % 2;
			
			boolean wavelengthFlexible = (k >= 1);
			
			String estrategia = (fibraFlexible ? "F" : "_");
			estrategia += (bandaFlexible ? "B" : "_");
			estrategia += (wavelengthFlexible ? "W" : "_");
			
			Configuration.setflexibility(Configuration.FIBER_INCREASE, fibraFlexible);
			Configuration.setflexibility(Configuration.BAND_INCREASE, bandaFlexible);
			Configuration.setflexibility(Configuration.WAVELENGTH_INCREASE, wavelengthFlexible);
			
			for ( int carga = 0; carga < 4; carga++){
				long actual = System.currentTimeMillis();
				System.out.print("\n[" + (actual-inicio)/1000 +"]Ejecucion " + (c*4 + carga + 1) + " de 128 : ");
				
				String sQuery = "From Caso where nombre = :nombre";
				TypedQuery<Caso> tQuery = em.createQuery(sQuery, Caso.class);
				String nombreCaso = "";
				
				switch(carga){
				case 0:
					nombreCaso = "NSFmin";
					break;
				case 1:
					nombreCaso = "NSFmidlow";
					break;
				case 2:
					nombreCaso = "NSFmidhigh";
					break;
				case 3:
					nombreCaso = "NSFmax";
					break;
				}
				
				tQuery.setParameter("nombre",nombreCaso);
				Caso caso = tQuery.getSingleResult();
	
				AlgoritmoGenetico ag = new AlgoritmoGenetico();
				System.gc();
				poblacion.clear();
				String corrida = "" + System.currentTimeMillis();
				corrida = AdministracionDatos.SHAsum(corrida.getBytes()).substring(0,5);
				
				System.out.print("Inicializacion");
				
				System.out.print("[" + (runtime.totalMemory() / 1024));
				
				for(int i = 0; i < 100; i++){
					Solucion individuo = new Solucion();
					individuo.setCaso(caso);
					individuo.random();
					poblacion.add(individuo);	
				} 
				
				System.out.print("-" + (runtime.totalMemory() / 1024) + "]");
								
				System.out.print("-Optimizacion");
				TorneoBinario selector = new TorneoBinario();
				selector.setMaxIndividuos(100);
				poblacion = new TreeSet<Individuo>(ag.optimizar(1000, poblacion, selector));
				Solucion mejor = (Solucion) poblacion.iterator().next();
				
				mejor.setNombre(nombreCaso+"-"+estrategia+"-"+(c / 8));
				
				System.out.print("-Persistencia");
			
				em.getTransaction().begin();
				em.persist(mejor);
				em.getTransaction().commit();
				
				mejor.genGraphs();
			}
			
		}
		
	}

}
